﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using ICSharpCode.TextEditor;
using ICSharpCode.TextEditor.Document;
using GeneratorLib.DB;
using GeneratorLib.DB.Connectios;
using GeneratorLib.DB.Schemas;


namespace DBExplorer.TemplateGenerators
{
    public partial class TemplateGenerator : Form, GeneratorLib.IGenerator
    {

        public IConnection Connection { get; set; }
        private TableInfo _table;
        public TableInfo Table
        {
            get
            {
                return _table;
            }
            set
            {
                _table = value;
                if (value != null)
                {
                    this.Text = string.Format("{0}", value.TableName);
                }

            }
        }

        //public string GeneratorName
        //{
        //    get
        //    {
        //        return this.Text;
        //    }
        //    set
        //    {
        //        this.Text = value;
        //    }
        //}

        public void AddToolStripItem(ToolStripItem item)
        {

        }


        private System.Timers.Timer formatTimer;

        public TemplateGenerator()
        {
            InitializeComponent();
            //this.TopLevel = false;

           // AddToolItems();
            //this.GeneratorName = "Tempalte Generator";


            this.tabControl1.SelectedIndex = 0;

            initEditor();

            formatTimer = new System.Timers.Timer(2000);
            formatTimer.Elapsed += new System.Timers.ElapsedEventHandler(formatTimer_Elapsed);
        }

        /*
        private void AddToolItems()
        {
            ToolStripMenuItem item0 = new ToolStripMenuItem("Generator");
            item0.Tag = 0;
            ToolStripMenuItem item11 = new ToolStripMenuItem("New...");
            item11.Tag = 11;
            ToolStripMenuItem item12 = new ToolStripMenuItem("Open...");
            item12.Tag = 12;
            ToolStripMenuItem item13 = new ToolStripMenuItem("Save");
            item13.Tag = 13;
            ToolStripMenuItem item14 = new ToolStripMenuItem("Save as...");
            item14.Tag = 14;

            this.AddToolStripItem(item0);
            this.AddToolStripItem(new ToolStripSeparator());
            this.AddToolStripItem(item11);
            this.AddToolStripItem(item12);
            this.AddToolStripItem(item13);
            this.AddToolStripItem(item14);
        }
        */

        public override int GetHashCode()
        {
            return string.Format("{0}{1}", this.Connection.ConnectStr, this.Table).GetHashCode();
        }

        public override bool Equals(object obj)
        {
            var obj2 = obj as TemplateGenerator;
            if (obj2 == null)
            {
                return false;
            }

            return obj2.Connection == this.Connection && obj2.Table == this.Table;
        }

        #region IGenerator
        public void Generate()
        {
            if (tabControl1.SelectedIndex == 0)
            {
                btGenerator_Click(btGenerator, EventArgs.Empty);
            }
            else if (tabControl1.SelectedIndex == 3)
            {
                btGenerator_Click(btGenerator2, EventArgs.Empty);
            }
        }    
        

        public void Generate(string command)
        {
            btGenerator_Click(null, EventArgs.Empty);
        }

        public void RefreshContent()
        {
        }

        public void Save()
        {
            Generate(toolStripButton4);
        }

        public bool CanSave()
        {
            return true;
        }
        public bool CanGenerate()
        {
            return true;
        }
        #endregion


        
        private void Generate(ToolStripItem item)
        {
            switch (Convert.ToInt32(item.Tag))
            {
                case 0:
                    btGenerator_Click(null,EventArgs.Empty);
                    break;
                case 11:
                    addNew();
                    break;
                case 12:
                    broweFile();
                    break;
                case 13:
                    saveFile(false);
                    break;
                case 14:
                    saveFile(true);
                    break;
                default:
                    break;
            }
        }
        


        void formatTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            formatTimer.Enabled = false;
            formatTimer.Stop();

            SetActiveEditor1HighlightingStrategy();
        }

        delegate void SetActiveEditor1HighlightingStrategyDelegate();
        private void SetActiveEditor1HighlightingStrategy()
        {
            if (this.InvokeRequired)
            {
                SetActiveEditor1HighlightingStrategyDelegate d 
                    = new SetActiveEditor1HighlightingStrategyDelegate(SetActiveEditor1HighlightingStrategy);

                this.Invoke(d);
            }
            else
            {

            TemplateToCode tToc = new TemplateToCode(this.Table, this.TemplateSource.Text); 
                if (tToc.TempalteConfig.FileType == null)
                    return;

                            ActiveEditor1.Document.HighlightingStrategy
                                = HighlightingStrategyFactory.CreateHighlightingStrategy(tToc.TempalteConfig.FileType.ToUpper());
            }
        }

        private void initEditor()
        {
            if (ActiveEditor1 != null)
            {
                ActiveEditor1.Document.HighlightingStrategy = HighlightingStrategyFactory.CreateHighlightingStrategy("HTML");
            }

            if (ActiveEditor2 != null)
            {
                ActiveEditor2.Document.HighlightingStrategy = HighlightingStrategyFactory.CreateHighlightingStrategy("C#");
            }

            if (ActiveEditor3 != null)
            {
                ActiveEditor3.Document.HighlightingStrategy = HighlightingStrategyFactory.CreateHighlightingStrategy("C#");
            }

            if (ActiveEditor4 != null)
            {
                ActiveEditor4.Document.HighlightingStrategy = HighlightingStrategyFactory.CreateHighlightingStrategy("HTML");
            }
        }

        private TemplateFile _templateFile;
        public TemplateFile TemplateFile
        {
            get
            {
                return _templateFile;
            }
            set
            {
                if (value == null)
                {
                    _templateFile = new TemplateFile("");
                }
                else
                {
                    _templateFile = new TemplateFile(value.FileName);
                }

                if (_templateFile.FileName.Length == 0)
                {
                    labTemplateFileName.Text = "";
                    TemplateSource.ResetText();
                    debugCode.Text = "";
                    CodeSource.Text = "";
                    templateToCode = null;
                }
                else
                {
                    labTemplateFileName.Text = _templateFile.FileName;
                    TemplateSource.LoadFile(_templateFile.FileName);
                    debugCode.Text = "";
                    CodeSource.Text = "";
                    templateToCode = null;
                }

                TemplateSource.Refresh();
                debugCode.Refresh();
                CodeSource.Refresh();

                SetTemplateChange(false);
                tabControl1.SelectedIndex = 0;
            }
        }

        private TextEditorControl ActiveEditor1
        {
            get
            {
                return this.TemplateSource;
            }
        }

        private TextEditorControl ActiveEditor2
        {
            get
            {
                return this.CodeSource;
            }
        }

        private TextEditorControl ActiveEditor3
        {
            get
            {
                return this.debugCode;
            }
        }

        private TextEditorControl ActiveEditor4
        {
            get
            {
                return this.txtReference;
            }
        }

        private void SetTemplateChange(bool changed)
        {
            if (changed)
                tabControl1.TabPages[0].Text = string.Format("{0}{1}", tabControl1.TabPages[0].Tag, "*");
            else
                tabControl1.TabPages[0].Text = string.Format("{0}{1}", tabControl1.TabPages[0].Tag, "");
        }

        TemplateToCode templateToCode = null;
        private void btGenerator_Click(object sender, EventArgs e)
        {
            string msg = "syntax error! Check File please!";

            templateToCode = null;

            if (sender == btGenerator)
                templateToCode = new TemplateToCode(this.Table, this.TemplateSource.Text);
            else if (sender == btGenerator2)
                templateToCode = new TemplateToCode(this.Table, this.txtReference.Text);

            if (templateToCode == null) return;

            if (templateToCode.CheckSyntax() == false)
            {
                MessageBox.Show(msg);
                return;
            }

            templateToCode.ConvertToCSharp();

            labAutoSave.Text = string.Format("{0}\\{1}", templateToCode.OutputConfig.GetAutoSavePath(), templateToCode.OutputConfig.GetAutoSaveFileName());
            debugCode.Text = templateToCode.DebugCode;
            CodeSource.Text = templateToCode.ResultCode;

            ActiveEditor2.Document.HighlightingStrategy
                = HighlightingStrategyFactory.CreateHighlightingStrategy(templateToCode.OutputConfig.FileType.ToUpper());

            tabControl1.SelectedIndex = 2;

        }
        
        private void TemplateSource_TextChanged(object sender, EventArgs e)
        {            
            formatTimer.Stop();
            formatTimer.Enabled = true;
            formatTimer.Start();

            SetTemplateChange(true);
        }



        private void addNew()
        {
            TemplateFile = new TemplateFile("");
        }
        private void broweFile()
        {
            openFileDialog1.ShowDialog();
        }

        private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
        {
            TemplateFile= new TemplateFile( openFileDialog1.FileName);
        }

        private void saveFile(bool saveAs)
        {
            TextEditorControl edit = null;
            string saveto = string.Empty;

            switch (tabControl1.SelectedIndex)
            {
                case 0:
                    edit = TemplateSource;
                    saveFileDialog1.Filter = string.Format("Template File({0})|{0}", "*.cmt");
                    if (TemplateFile !=null && TemplateFile.FileName.Length > 0 && !saveAs)
                    {
                        saveto = TemplateFile.FileName;
                    }
                    break;
                case 1:
                    saveFileDialog1.Filter = string.Format("Code Fragment({0})|{0}", "*.txt");
                   edit = debugCode;
                    break;
                case 2:
                    string Extension =".cs";
                    if (templateToCode != null)
                    {
                        Extension=templateToCode.OutputConfig.Extension;
                    }
                    saveFileDialog1.Filter = string.Format("Code(*{0})|*{0}", Extension);
                    edit = CodeSource;
                    break;
                default:
                    break;
            }

            if (edit == null)
            {
                return;
            }

            if (saveto == string.Empty && saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                saveto = saveFileDialog1.FileName;
            }

            if (saveto == string.Empty)
            {
                return;
            }
            try
            {
                edit.SaveFile(saveto);
                if (edit == TemplateSource && (TemplateFile==null || TemplateFile.FileName.Length == 0 || saveAs))
                {
                    if (TemplateFileAdded != null)
                        TemplateFileAdded(this, EventArgs.Empty);

                    TemplateFile = new TemplateFile(saveto);
                }
                else if (edit == TemplateSource){
                        SetTemplateChange(false);
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

        }

        private void btSaveDebug_Click(object sender, EventArgs e)
        {
            saveFile(true);
        }

        private void btSaveCode_Click(object sender, EventArgs e)
        {
            saveFile(true);
        }

        /*
        public override void Save()
        {
            base.Save();
            saveFile(false);
        }
        */

        private void TemplateSource_Load(object sender, EventArgs e)
        {

        }

        private void txtReference_Load(object sender, EventArgs e)
        {

        }

        private void tabControl1_TabIndexChanged(object sender, EventArgs e)
        {
        }

        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (tabControl1.SelectedIndex == 3 && txtReference.Text.Length == 0)
            {
                txtReference.LoadFile(System.IO.Path.Combine(GlobalValues.CurrentPath, "Addins/Object Property.cmt"));
                TemplateToCode t = new TemplateToCode(this.Table, this.txtReference.Text);
                ActiveEditor4.Document.HighlightingStrategy
                    = HighlightingStrategyFactory.CreateHighlightingStrategy(t.TempalteConfig.FileType.ToUpper());

            }
        }

        public event EventHandler TemplateFileAdded;

        private void toolStripButton_Click(object sender, EventArgs e)
        {
            Generate((ToolStripItem)sender);
        }
    }
}
